package leetcode101.graph;

import java.util.Deque;
import java.util.LinkedList;

/**
 * @author Synhard
 * @version 1.0
 * @class Graph
 * @description 785. 判断二分图
 * 存在一个 无向图 ，图中有 n 个节点。其中每个节点都有一个介于 0 到 n - 1 之间的唯一编号。给你一个二维数组 leetcode101.graph ，
 * 其中 leetcode101.graph[u] 是一个节点数组，由节点 u 的邻接节点组成。形式上，对于 leetcode101.graph[u] 中的每个 v ，
 * 都存在一条位于节点 u 和节点 v 之间的无向边。该无向图同时具有以下属性：
 * 不存在自环（leetcode101.graph[u] 不包含 u）。
 * 不存在平行边（leetcode101.graph[u] 不包含重复值）。
 * 如果 v 在 leetcode101.graph[u] 内，那么 u 也应该在 leetcode101.graph[v] 内（该图是无向图）
 * 这个图可能不是连通图，也就是说两个节点 u 和 v 之间可能不存在一条连通彼此的路径。
 * 二分图 定义：如果能将一个图的节点集合分割成两个独立的子集 A 和 B ，并使图中的每一条边的两个节点一个来自 A 集合，
 * 一个来自 B 集合，就将这个图称为 二分图 。
 *
 * 如果图是二分图，返回 true ；否则，返回 false 。
 *
 *  
 *
 * 示例 1：
 *
 *
 * 输入：leetcode101.graph = [[1,2,3],[0,2],[0,1,3],[0,2]]
 * 输出：false
 * 解释：不能将节点分割成两个独立的子集，以使每条边都连通一个子集中的一个节点与另一个子集中的一个节点。
 * 示例 2：
 *
 *
 * 输入：leetcode101.graph = [[1,3],[0,2],[1,3],[0,2]]
 * 输出：true
 * 解释：可以将节点分成两组: {0, 2} 和 {1, 3} 。
 *
 * @tel 13001321080
 * @email 823436512@qq.com
 * @date 2021-06-30 7:18
 */
public class Code1 {

    public static void main(String[] args) {
        int[][] graph = new int[][]{{1,2,3},{0,2},{0,1,3},{0,2}};
        System.out.println(isBipartite(graph));
    }

    public static boolean isBipartite(int[][] graph) {
        if (graph.length == 0) {
            return false;
        }
        int[] colors = new int[graph.length];
        for (int i = 0; i < graph.length; i++) {
            if (colors[i] == 0) {
                colors[i] = 1;
            }
            Deque<Integer> queue = new LinkedList<>();
            queue.addLast(i);
            while(!queue.isEmpty()) {
                int cur = queue.removeFirst();
                int color = colors[cur];
                for (int j = 0; j < graph[cur].length; j++) {
                    if (colors[graph[cur][j]] == 0) {
                        colors[graph[cur][j]] = color == 1 ? -1 : 1;
                        queue.addLast(graph[cur][j]);
                    } else {
                        if (colors[graph[cur][j]] == color) {
                            return false;
                        }
                    }
                }
            }
        }
        return true;
    }

}
/*
对于图的广度优先搜索来说，while外面要套一层for确保整个图的每一个结点都遍历到了
idea中shift + F6 快速选中所有相同名称的变量
 */